<?php

namespace lemon\models\traits;

use Yii;
use yii\imagine\Image;
use yii\web\UploadedFile;
use yii\helpers\ArrayHelper;
use lemon\repository\Union;
use lemon\repository\Qiniu;
use backend\repository\Helpers;

/**
 * 
 */
trait UploadTrait
{
	private $froms = [ 1=>'UKN', 2=>'H51', 3=>'ADM', 4=>'IOS', 5=>'AND', 9=>'UKN'];
	private $allowtype = ['image/jpeg','image/jpg','image/png','image/pjpeg','image/gif', 'image/svg+xml', 'application/octet-stream', 'multipart/form-data'];
	
	public function tempFile($model, $field, &$ext){
		$formName = strtolower($model->formName());
		$upload_file = UploadedFile::getInstanceByName('up'.$formName.'-'.$field);
		if ($upload_file) {
			$ext = $upload_file->extension;
			return $upload_file->tempName;
		}else{
			$ext="";
			return "";
		}
	}
	/**
	 *
	 * @param unknown $model
	 * @param unknown $field
	 * @throws \Exception
	 * @return string
	 */
	public function saveImage($model, $field, $multi= FALSE, $options=[]){
		$formName = strtolower($model->formName());
		$files= UploadedFile::getInstancesByName('up'.$formName.'-'.$field);
		if ($files) {
			$saved_file = $this->storeImage($files, $options);
			if($multi){
				return $saved_file;
			}else{
				if(count($saved_file['s'])==1){
					return $saved_file['s'][0];
				}else{
					return $saved_file['f'][0];
				}
			}
		}
		return [];
	}
	
	/*
	 8*/
	/**
	 * 存储图片、文件等
	 * @param unknown $files 上传的文件, 数组元素格式:['name'=>"xxx.png", 'tempName'=>"C:\Windows\Temp\php70F0.tmp", 'type'=>"image/png", 'size'=>80053]
	 * @param number $from 上传的客户端类型 1未知 2H5网页 3后台 4苹果的iOS系统 5安卓系统
	 * @param string $folder 保存的目录
	 * @param array $thumbs 需要生成的缩略图，包含KEY键的数组，每个元素的值为宽高，如：'S'=>[100, 100]
	 * @param array $fixed_size 固定图片大小，首元素如果为s,表示固定大小，首元素如果为w表示固定宽度。 ['s',]
	 * @param string $need_size 是否需要返回图片大小
	 * @param string $prefix 文件名 的前缀
	 * @param array $compress 是否存原图及压缩，no不存原图，su压缩成宽为400（最大）的图，bd压缩成宽为900（最大）的图
	 * @throws \Exception
	 * @return string[][]|NULL[][][]|unknown[][][]
	 */
	public function storeImage($files, $options=[]){
		$config= ['folder'=>'zo', 'from'=>3, 'thumbs' =>[], 'fixed_size'=>[], 'need_size'=>FALSE, 'prefix'=>'', 'compress'=>'bd', 'id'=>0];
		if(!empty($options)){
			$config= ArrayHelper::merge($config, $options);
		}
		$month = Union::month2Number();
		$physical_path = Yii::$app->params['FILE_PHYSICAL_PATH'];
		$upload_path = $config['folder']."/$month/";
		$full_path = $physical_path . $upload_path;
		
		if (!is_dir($full_path)) {
			if (!mkdir($full_path, 0777, true)) {
				throw new \Exception('目录不存在');
			}
		}
		$success = [];
		$fail = [];
		foreach ($files as $file){
			$original = $file->name;
			try{
				$result = [];
				$type=$file->type;
				$size=$file->size;
				$extension = $file->extension;
				if(!in_array($type, $this->allowtype)){
					throw new \Exception('图片格式不正确');
				}
				if($size>5000000){
					throw new \Exception('图片大小不超过4M');
				}
				if($config['id']>0){
					$num = $config['id'];
					if($num>46655){
						$num %= 46655;
					}
					$name = base_convert($num, 10, 36).'_'.$this->randomChar(2);
				}else{
					$name = $config['prefix'].$this->randomChar(6);
				}
				$filename = $name.'.'.$extension;
				
				$fixed=$config['fixed_size'];
				$compress = $config['compress'];
				$crop_width = $crop_height = 0;
				
				$area = getimagesize($file->tempName);
				$width = $area[0];
				$height = $area[1];
				if($compress!='no'){
					$full_path2 = $physical_path .$config['folder']."s/$month/";
					if (!is_dir($full_path2)) {
						if (!mkdir($full_path2, 0777, true)) {
							throw new \Exception('目录不存在');
						}
					}
					$save_result = $file ->saveAs($full_path2.$filename);
					if (!$save_result) {
						throw new \Exception("文件保存失败");
					}
				}
				
				if(count($fixed)>0){
					if($fixed[0] == 's' && ($width!=$fixed[1] || $height!=$fixed[2])){
						$crop_width = $fixed[1];
						$crop_height = $fixed[2];
					}elseif($fixed[0] == 'w' && $width!=$fixed[1]){
						$crop_width = $fixed[1];
					}
				}elseif($compress=='bd' && $width>900){
					$crop_width = 900;
				}elseif($compress=='su' && $width>400){
					$crop_width = 400;
				}
				if($crop_width==0){
					if($compress=='no'){
						$save_result = $file ->saveAs($full_path.$filename);
					}else{
						$save_result = copy($full_path2.$filename, $full_path.$filename);
					}
					if($config['need_size']){
						$result['w'] = $width;
						$result['h'] = $height;
					}
				}else{
					if($crop_height==0){
						$crop_height = round($crop_width*$height/$width);
					}
					$save_result = $this->thumbnail($compress=='no'?$file->tempName:$full_path2.$filename, $full_path.$filename, $crop_width, $crop_height, $extension);
					if($config['need_size']){
						$result['w'] = $crop_width;
						$result['h'] = $crop_height;
					}
				}
				if (!$save_result) {
					throw new \Exception("文件保存失败");
				}
				
				$result['n'] = mb_substr($original, 0, mb_strripos($original, '.'));//name
				$result['f'] = $filename;//filename
				$result['u'] = $upload_path.$filename;//url
				$result['t'] = count($config['thumbs'])>0?$this->makeThumb($full_path.$name, $upload_path.$name, $extension, $config['thumbs']):[];//thumbs, 生成缩略图
				$success[] = $result;
			}catch(Exception $ex){
				$fail[] = ['n'=>$original, 'm'=>$ex->getMessage()];
			}
		}
		return ['s'=>$success, 'f'=>$fail];
	}
	
	/**
	 * 
	 * @param unknown $files
	 * @param array $options
	 * @param number $from 上传的客户端类型 1未知 2H5网页 3后台 4苹果的iOS系统 5安卓系统
	 * @param string $folder 保存的目录
	 * @param array $thumbs 需要生成的缩略图，包含KEY键的数组，每个元素的值为宽高，如：'S'=>[100, 100]
	 * @param array $fixed_size 固定图片大小，数组第一元素 s表示固定宽高，w表示固定宽（不超过）
	 * @param string $need_size 是否需要返回图片大小
	 * @param string $prefix 文件名 的前缀
	 * @throws \Exception
	 * @return array
	 */
	public function storeImageNet($files, $options=[], $time=null){
		$config= ['folder'=>'wn', 'from'=>3, 'thumbs' =>[], 'fixed_size'=>[], 'need_size'=>FALSE, 'prefix'=>''];
		if(!empty($options)){
			$config= ArrayHelper::merge($config, $options);
		}
		$month = Union::month2Number($time);
		
		$physical_path = Yii::$app->params['FILE_PHYSICAL_PATH'];
		$upload_path = $config['folder']."/$month/";
		$full_path = $physical_path . $upload_path;
		
		if (!is_dir($full_path)) {
			if (!mkdir($full_path, 0777, true)) {
				throw new \Exception('目录不存在');
			}
		}
		$fixed_size=$config['fixed_size'];
		$crop_width = $crop_height = 0;
		if(count($fixed_size)>0){
			if($fixed_size[0] == 's'){
				$crop_width = $fixed_size[1];
				$crop_height = $fixed_size[2];
			}elseif($fixed_size[0]= 'w'){
				$crop_width = $fixed_size[1];
				$crop_height = 100000;
			}
		}
		
		$success = [];
		$fail = [];
		foreach ($files as $key=>$original){
			try{
				$result = [];
				$extension = Union::deExtension($original);
				if($config['prefix']){
					$filename = $config['prefix'].'z'.base_convert($key+1, 10, 36);
				}else{
					$filename = $config['from'].$this->randomChar(10);
				}
				
				$resource = fopen($original, 'r');
				if($crop_width>0 && $crop_height>0){
					if($fixed_size[0]= 'w'){
						$img_data = getimagesize($original);
						if($crop_width<$img_data[0]){
							$crop_height = round($crop_width*$img_data[1]/$img_data[0]);
						}else{
							$crop_width = $img_data[0];
							$crop_height = $img_data[1];
						}
					}
					$save_result = $this->thumbnail($resource, $full_path.$filename.'.' . $extension, $crop_width, $crop_height);
					if($config['need_size']){
						$result['w'] = $crop_width;
						$result['h'] = $crop_height;
					}
				}else{
					$save_result = file_put_contents($full_path.$filename.'.' . $extension, $resource);
					if($config['need_size']){
						$img_data = getimagesize($original);
						$result['w'] = $img_data[0];
						$result['h'] = $img_data[1];
					}
				}
				fclose($resource);
				
				if (!$save_result) {
					throw new \Exception("文件保存失败");
				}
				$result['n'] = '';//name
				$result['f'] = $filename.'.' . $extension;//filename
				$result['u'] = $upload_path.$filename.'.' . $extension;//url
				$result['t'] = count($config['thumbs'])>0?$this->makeThumb($full_path.$filename, $upload_path.$filename, $extension, $config['thumbs']):[];//thumbs, 生成缩略图
				
				$success[$key] = $result;
			}catch(\Exception $ex){
				$fail[$key] = ['n'=>$original, 'm'=>$ex->getMessage()];
			}
		}
		return ['s'=>$success, 'f'=>$fail];
	}
	
	public function storeToQiniu($files, $uploading=FALSE, $dellocal=FALSE, $time=null){
		$physical_path = Yii::$app->params['FILE_PHYSICAL_PATH'];
		$month = Union::month2Number($time);
		$params = Yii::$app->params['QINIU'];
		$ak = $params['ak'];
		$sk = $params['sk'];
		$domain = $params['domain'];
		$http = $params['http'];
		$bucket = $params['bucket'];
		$zone = $params['zone'];
		$prefix= $params['prefix'];
		
		$qiniu = new Qiniu($ak, $sk, $domain, $bucket, $zone);
		
		$result=[];
		$success = [];
		$fail = [];
		foreach ($files as $key => $file){
			if($uploading){
				$original = $file->tempName;
				$filename = '8'.$this->randomChar(10).'.'.$file->extension;
				$name = $file->name;
			}else{
				$original = $physical_path.$file['u'];
				$filename = $file['f'];
				$name = $file['u'];
			}
			try{
				$qiniu->uploadFile($original, $month.'/'.$filename);
				$file['u'] = $prefix.":".$month.'/'.$filename;
				$success[$key] = $file;
				if($dellocal){
					unlink($original);
				}
			}catch(\Exception $ex){
				$fail[$key] = ['n'=>$name, 'm'=>$ex->getMessage()];
			}
		}
		return ['s'=>$success, 'f'=>$fail];
	}
	public function storeThumb($original, $thumbs =[]){
		$physical_path = Yii::$app->params['FILE_PHYSICAL_PATH'];
		$filename = $original;//路径和文件名
		$extension = "";
		$pos = strrpos($original, ".");
		if($pos){
			$filename= substr($original, 0, $pos);
			$extension= substr($original, $pos+1);
		}
		return $this->makeThumb($physical_path.$filename, $filename, $extension, $thumbs);
	}
	
	/**
	 * 
	 * @param String $original 图片网址
	 * @param String $image1 保存的原图路径
	 * @param String $image2 保存的压缩图路径
	 */
	function backupImage($image1, $image2, $original="", $save1=TRUE){
		$result = false;
		try{
			$extension =  Union::deExtension($original);
			$image1 .= '.'.$extension;
			$image2 .= '.'.$extension;
			if($save1){
				$resource0 = file_get_contents($original);
				$resource = imagecreatefromstring($resource0);
				if($resource!==false){
					if($extension=="png"){
						imagepng($resource, $image1);
					}else{
						imagejpeg($resource, $image1, 90);
					}
					imagedestroy($resource);
				}
			}
			$size = getimagesize($image1);
			$w = $size[0];
			$h = $size[1];
			if(($w>=$h && $w>500) || ($w<$h && $w>300)){
				$width = $w>=$h ? 500:300;
				$height = intval($h*$width/$w);
				if($width>0 && $height>0){
					$result = $this->thumbnail($image1, $image2, $width, $height, $extension);
				}else{
					$result = copy($image1, $image2);
				}
			}else{
				$result = copy($image1, $image2);
			}
		}catch (Exception $ex){
			$result = false;
		}
		return $result;
	}
	
	/**
	 * 生成缩略图
	 * @param string $original 文件全路径，不包含后缀
	 * @param string $original 文件相对路径，不包含后缀
	 * @param string $extension 文件后缀，包含点
	 * @param array $thumbs
	 */
	private function makeThumb($original, $relative, $extension, $thumbs =[]){
		$result = [];
		foreach ($thumbs as $key=>$val){
			$width = 100;
			$height = 100;
			if(is_array($val)){
				$width = $val[0];
				$height = $val[1];
			}elseif (is_numeric($val)){
				$width = $height = $val;
			}
			$this->thumbnail($original.$extension, $original.'_'.$key.'.' . $extension, $width, $height, $extension);
			$result[$key] = $relative.'_'.$key.'.' . $extension;
		}
		return $result;
	}
	
	function thumbnail($path, $thumb, $width, $height, $extension='jpg'){
		$result = FALSE;
		try{
			$quality = 80;
			if($extension=="png"){
				$source = imagecreatefrompng($path);
			}elseif($extension=="gif"){
				$source = imagecreatefromgif($path);
			}else{
				$source = imagecreatefromjpeg($path);
			}
			$width0 = imagesx($source);
			$height0 = imagesy($source);
			$image = imagecreatetruecolor($width, $height);
			$ratio1 = $width/$height;
			$ratio2 = $width0/$height0;
			$x = 0;
			$y = 0;
			if($ratio1>$ratio2){
				$h = $height0;
				$height0 = intval($width0*$height/$width);
				$y = intval(($h-$height0)/2);
			}elseif($ratio1<$ratio2){
				$w = $width0;
				$width0 = intval($width*$height0/$height);
				$y = intval(($w-$width0)/2);
			}
			imagecopyresampled($image, $source, 0, 0, $x, $y, $width, $height, $width0, $height0);
			
			if($extension=="png"){
				imagepng($image, $thumb);
			}else{
				imagejpeg($image, $thumb, $quality);
			}
			imagedestroy($source);
			imagedestroy($image);
			$result = TRUE;
		}catch(Exception $ex){
			echo "<br>".$ex->getMessage();
		}
		return $result;
	}
	
	public function randomChar($len){
		$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		mt_srand(10000000*(double)microtime());
		for ($i = 0, $str = '', $lc = strlen($chars)-1; $i < $len; $i++){
			$str .= $chars[mt_rand(0, $lc)];
		}
		return $str;
	}
}